{%- set inherits = class['inherits'] -%}
{%- if inherits == 'Object'%}
  {%- set inherits = 'GodotObject' -%}
{%- endif %}

{%- macro extends(class) -%}
{%- if inherits -%}
 extends {{inherits}}
{%- endif -%}
{%- endmacro -%}

{%- set class_name = class['name'] -%}
{%- if class_name == 'Object'%}
  {%- set class_name = 'GodotObject' -%}
{%- endif %}

{%- for den in dependency %}
  {%- if den == 'Object' %}
    {%- set den = 'GodotObject' %}
    {%- if den != class_name %}
import { {{den}} } from "@godot/classes/{{camel_to_snake(den)}}";
    {%- endif %}
  {%- else %}
    {%- if den != class_name %}
import { {{den}} } from "@godot/classes/{{camel_to_snake(den)}}";
    {%- endif %}
  {%- endif %}
{%- endfor %}

{%- macro process_vararg(is_vararg, arg) %}
  {%- if is_vararg -%}
    {%- if arg -%}
, ...arg: {{set_type(arg['type'])}}
    {%- else -%}
...arg: any
    {%- endif -%}
  {%- endif -%}
{%- endmacro %}
{%- macro is_static(method) %}
{%- if method['is_static'] %}
 static
{%- endif %}
{%- endmacro -%}
{%- macro is_singleton() -%}
{{'_' if class_name in singletons | map(attribute='type') | list else ''}}{{class_name}}
{%- endmacro %}
{%- if class_name in singletons | map(attribute='type') | list %}
declare global {
{%- endif %}
export declare class {{is_singleton()}} {{extends(class)}}{
  {%- for method in class['methods'] %}
    {%- if not class_name+':'+method['name'] in invalid_methods %}
      {%- if class_name == 'Node' %}
        {%- if method['name'] == 'get_node' or method['name'] == 'get_parent' %}
  public{{is_static(method)}} {{method['name']}}<T extends Node>({{connect_args(method['arguments']) + process_vararg(method['is_vararg'], method['arguments']|last)}}): T;
        {%- else %}
  public{{is_static(method)}} {{method['name']}}({{connect_args(method['arguments']) + process_vararg(method['is_vararg'], method['arguments']|last)}}){{set_return(method['return_value']['type'] if method['return_value'] else None)}};
        {%- endif %}
      {%- else %}
  public{{is_static(method)}} {{method['name']}}({{connect_args(method['arguments']) + process_vararg(method['is_vararg'], method['arguments']|last)}}){{set_return(method['return_value']['type'] if method['return_value'] else None)}};
      {%- endif %}
    {%- endif %}
  {%- endfor %}
  {%- for prop in class['properties'] %}
  {%- if prop['getter'] %}
  public get {{prop['name']}}(){{set_return(prop['type'])}};
  {%- endif %}
  {%- if prop['setter'] %}
  public set {{prop['name']}}(value): void;
  {%- endif %}
  {%- endfor %}
  {%- for enum in class['enums'] %}
  static {{enum['name']}} = {
    {%- for value in enum['values'] %}
    {{value['name']}} = {{value['value']}},
    {%- endfor %}
  }
  {%- endfor %}
  {%- for signal in class['signals'] %}
  public get {{signal['name']}}(): Signal;
  {%- endfor %}
}
{%- if class_name in singletons | map(attribute='type') | list %}
const {{class_name}}: _{{class_name}};
}
{%- endif %}